package com.dirox.confluence.labelmanagement.action;

import com.atlassian.confluence.core.Beanable;
import com.atlassian.confluence.core.ConfluenceActionSupport;
import com.atlassian.confluence.core.service.ValidationError;
import com.atlassian.confluence.labels.LabelManager;
import com.atlassian.confluence.spaces.SpaceManager;
import com.atlassian.confluence.util.ajax.AjaxResponse;

import com.dirox.confluence.labelmanagement.action.RenameLabelAjaxAction;
import com.dirox.confluence.labelmanagement.service.LabelManagementService;
import static com.google.common.base.Preconditions.checkNotNull;

import org.apache.commons.lang.StringUtils;

import org.apache.log4j.Logger;

/**
 * RenameLabelAjaxAction extends ConfluenceActionSupport implements Beanable
 * <p>
 * This class implement rename label action.
 *
 */
public class RenameLabelAjaxAction extends ConfluenceActionSupport
    implements Beanable {
    private static final long serialVersionUID = 1L;
    private static Logger log = Logger.getLogger(RenameLabelAjaxAction.class);
    private LabelManager labelManager;
    private Object bean;
    private SpaceManager spaceManager;
    private LabelManagementService labelManagementService;
    private String oldLabel;
    private String newLabel;
    private String spaceKey;

    /**
     * This method executes the rename label action
     *
     * @return the result of action in String (ERROR|SUCCESS)
     * @throws Exception
     */
    public String renameLabel() throws Exception {
        // Validating label names and space key.
        if (!validateInput()) {
            return ERROR;
        }

        try {
            // Check if spaceKey is not blank then rename in this space,
            // else rename in all spaces.
            if (StringUtils.isNotBlank(spaceKey)) {
                labelManagementService.renameLabelInSpace(spaceKey, oldLabel,
                    newLabel);
            } else {
                labelManagementService.renameLabelInAllSpaces(oldLabel, newLabel);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e.getCause());
            bean = AjaxResponse.failure(getText(e.getMessage()));

            return ERROR;
        }

        bean = AjaxResponse.success(getText("label-management.code.success"));

        return SUCCESS;
    }

    /**
     * Method for validating input for rename label action.
     * <p>
     * - Validate if labels are empty, return false.<br/>
     * - Validate if the new label contains "space" character<br/>
     * - Validate if two labels are the same, return false.<br/>
     * - Validate if old label does not exist, return false.<br/>
     * - Validate if space does not exist (when space is specified)
     * @return boolean
     */
    private boolean validateInput() {
        // check if the labels are empty
        if (StringUtils.isBlank(oldLabel) || StringUtils.isBlank(newLabel)) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.empty.label"));

            return false;
        }

        // check if the new label contains "space" character
        if (newLabel.contains(" ")) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.space.character"));

            return false;
        }

        // validate label
        ValidationError error = labelManagementService.getLabelValidationError(newLabel);

        if (error != null) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.invalid.character"));

            return false;
        }

        // check if the labels are the same
        if (newLabel.equalsIgnoreCase(oldLabel)) {
            // @TODO: need to correct error message
            bean = AjaxResponse.failure(getText(
                        "label-management.error.existed.label"));

            return false;
        }

        // check if the old label does not exist
        if (labelManager.getLabel(oldLabel) == null) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.not.exist.label"));

            return false;
        }

        // check if the space does not exist
        if (StringUtils.isNotBlank(spaceKey) &&
                (spaceManager.getSpace(spaceKey) == null)) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.not.exist.space"));

            return false;
        }

        // check if newLabel exists
        boolean isNewLabelExisted = false;

        if (StringUtils.isNotBlank(spaceKey)) {
            isNewLabelExisted = labelManagementService.isExistLabelInSpace(spaceKey,
                    newLabel);
        } else {
            isNewLabelExisted = labelManagementService.isExistLabel(newLabel);
        }

        if (isNewLabelExisted == true) {
            bean = AjaxResponse.failure(getText(
                        "label-management.error.exist.label"));

            return false;
        }

        return true;
    }

    @Override
    public Object getBean() {
        return bean;
    }

    public String getOldLabel() {
        return oldLabel;
    }

    public void setOldLabel(String oldLabel) {
        this.oldLabel = oldLabel;
    }

    public String getNewLabel() {
        return newLabel;
    }

    public void setNewLabel(String newLabel) {
        this.newLabel = newLabel;
    }

    public String getSpaceKey() {
        return spaceKey;
    }

    public void setSpaceKey(String spaceKey) {
        this.spaceKey = spaceKey;
    }

    public void setLabelManager(LabelManager labelManager) {
        this.labelManager = checkNotNull(labelManager);
    }

    public void setSpaceManager(SpaceManager spaceManager) {
        this.spaceManager = checkNotNull(spaceManager);
    }

    public void setLabelManagementService(
        LabelManagementService labelManagementService) {
        this.labelManagementService = checkNotNull(labelManagementService);
    }
}
